package helexis.game.tyrian.service;

import helexis.game.tyrian.Tyrian;
import helexis.game.tyrian.domain.Profile;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.Json;

public class ProfileManager {
	
	/**
	 * Profile 을 저장하는 데이터 파일
	 */
	private static final String PROFILE_DATA_FILE = "./tyrian/profile-v1.json";
	
	/**
	 * 로딩한 Profile
	 */
	private Profile profile;
	
	
	public ProfileManager() {
		
	}//end of constructor()
	
	
	public Profile retrieveProfile() {
		
		Gdx.app.log(Tyrian.LOG, "Retrieving profile...");
		
		/*
		 * 이미 로딩된 것이 있다면, 그냥 그걸 리턴합니다.
		 */
		if (this.profile != null) {
			return this.profile;
		}//end if
		
		/*
		 * Tutorial 5.
		 * 
		 * 파일을 로딩하기 위한 핸들을 가져옵니다.
		 * 
		 * Tutorial 8.
		 * 
		 * 파일을 로딩하기 위한 위치를 external 에서 local 로 변경함
		 * 
		 * 다음의 3가지 이유로 변경하는 것이 좋다고 함 !
		 * 
		 *  (1) when the application is removed, so are these files
		 *  (2) the SD Card is not always available
		 *  (3) the files are private to the application
		 */
//		FileHandle profileDataFile = Gdx.files.external(PROFILE_DATA_FILE);
		FileHandle profileDataFile = Gdx.files.local(PROFILE_DATA_FILE);
		
		Json json = new Json();
		
		/*
		 * 파일이 존재한다면, 로딩합니다.
		 */
		if (profileDataFile.exists()) {
			
			try {
				
				/*
				 * 파일을 로딩하는 순서는 다음과 같습니다.
				 * 
				 * 1. 파일로부터 텍스트 로딩
				 * 2. 로딩한 텍스트를 BASE64 디코딩하여 JSON 포맷으로 변경..
				 * 3. JSON 포맷의 텍스트를 Profile 객체로 변경 !
				 */
				
				String profileAsCode = profileDataFile.readString();
				
				String profileAsText = Base64Coder.decodeString(profileAsCode);
				
				this.profile = json.fromJson(Profile.class, profileAsText);
				
			} catch (Exception e) {
				
				Gdx.app.error(Tyrian.LOG, "Unable to parse existing profile data file...", e);
				
				/*
				 * 파일 로딩 중 오류가 발생하면,
				 * 파일이 없다치고 새로 생성하고 저장합니다.
				 */
				this.profile = new Profile();
				this.persist(this.profile);
				
			}//end try catch
			
		} else {
			
			/*
			 * 파일이 존재하지 않는다면,
			 * 새로 생성하고 저장합니다.
			 */
			this.profile = new Profile();
			this.persist(this.profile);
			
		}//end if else
		
		
		/*
		 * 저장된 파일을 읽어서 로딩했거나,
		 * 혹은 저장된 파일이 없어서 새로 생성하고 저장했거나,...
		 * Profile 을 리턴합니다.
		 */
		
		return this.profile;
		
	}//end of retrieveProfile()
	
	
	/**
	 * 주어진 Profile 을 인코딩하여 지정된 파일에 씁니다.
	 * 
	 * @param profile 저장하려는 Profile
	 */
	public void persist(Profile profile) {
		
		Gdx.app.log(Tyrian.LOG, "Persisting profile...");
		
		/*
		 * 파일을 저장하는 순서는 다음과 같습니다.
		 * 
		 * 1. 파일을 JSON 포맷으로 변경
		 * 2. JSON 텍스트를 BASE64 인코딩
		 * 3. 파일로 저장 !
		 */
		
		Json json = new Json();
		
		FileHandle profileDataFile = Gdx.files.external(PROFILE_DATA_FILE);
		
		String profileAsText = json.toJson(profile);
		
		String profileAsCode = Base64Coder.encodeString(profileAsText);
		
		profileDataFile.writeString(profileAsCode, false);
		
	}//end of persist()
	
	
	/**
	 * 플레이어의 Profile 을 저장합니다.
	 * 
	 * 만약 Profile 이 없다면, 아무것도 하지 않습니다.
	 */
	public void persist() {
		
		if (this.profile != null) {
			this.persist(this.profile);
		}//end if
		
	}//end of persist()
	
	

}
//end of ProfileService.java
